//by mircemk, June 2026 #include "unihiker_k10.h" #include #include "esp_camera.h" UNIHIKER_K10 k10; TFT_eSPI tft = TFT_eSPI(); uint8_t screen_dir = 2; // K10 GC2145 camera pins #define XCLK_GPIO_NUM 7 #define SIOD_GPIO_NUM 47 #define SIOC_GPIO_NUM 48 #define Y9_GPIO_NUM 6 #define Y8_GPIO_NUM 15 #define Y7_GPIO_NUM 16 #define Y6_GPIO_NUM 18 #define Y5_GPIO_NUM 9 #define Y4_GPIO_NUM 11 #define Y3_GPIO_NUM 10 #define Y2_GPIO_NUM 8 #define VSYNC_GPIO_NUM 4 #define HREF_GPIO_NUM 5 #define PCLK_GPIO_NUM 17 void setupCamera() { camera_config_t config; config.ledc_channel = LEDC_CHANNEL_0; config.ledc_timer = LEDC_TIMER_0; config.pin_d0 = Y2_GPIO_NUM; config.pin_d1 = Y3_GPIO_NUM; config.pin_d2 = Y4_GPIO_NUM; config.pin_d3 = Y5_GPIO_NUM; config.pin_d4 = Y6_GPIO_NUM; config.pin_d5 = Y7_GPIO_NUM; config.pin_d6 = Y8_GPIO_NUM; config.pin_d7 = Y9_GPIO_NUM; config.pin_xclk = XCLK_GPIO_NUM; config.pin_pclk = PCLK_GPIO_NUM; config.pin_vsync = VSYNC_GPIO_NUM; config.pin_href = HREF_GPIO_NUM; config.pin_sscb_sda = SIOD_GPIO_NUM; config.pin_sscb_scl = SIOC_GPIO_NUM; config.pin_pwdn = -1; config.pin_reset = -1; config.xclk_freq_hz = 20000000; config.pixel_format = PIXFORMAT_RGB565; config.frame_size = FRAMESIZE_QVGA; // 240x320 on K10 config.jpeg_quality = 12; config.fb_count = 1; config.fb_location = CAMERA_FB_IN_PSRAM; config.grab_mode = CAMERA_GRAB_WHEN_EMPTY; esp_err_t err = esp_camera_init(&config); if (err != ESP_OK) { Serial.printf("Camera init failed: 0x%x\n", err); while (1) delay(1000); } sensor_t *s = esp_camera_sensor_get(); s->set_vflip(s, 1); s->set_hmirror(s, 0); Serial.println("Camera OK"); } String detectColorFromCenter(camera_fb_t *fb) { long rSum = 0, gSum = 0, bSum = 0; int count = 0; int startX = 80; int endX = 160; int startY = 90; int endY = 190; uint16_t *pixels = (uint16_t *)fb->buf; for (int y = startY; y < endY; y += 2) { for (int x = startX; x < endX; x += 2) { uint16_t c = pixels[y * fb->width + x]; uint8_t g = ((c >> 11) & 0x1F) << 3; uint8_t b = ((c >> 5) & 0x3F) << 2; uint8_t r = (c & 0x1F) << 3; rSum += r; gSum += g; bSum += b; count++; } } int r = rSum / count; int g = gSum / count; int b = bSum / count; Serial.printf("CENTER RGB: R=%d G=%d B=%d\n", r, g, b); if (r > g + 35 && r > b + 35) return "RED OBJECT"; if (g > r + 35 && g > b + 35) return "GREEN OBJECT"; if (b > r + 35 && b > g + 35) return "BLUE OBJECT"; if (r > 150 && g > 150 && b < 100) return "YELLOW OBJECT"; if (r < 60 && g < 60 && b < 60) return "DARK OBJECT"; if (r > 180 && g > 180 && b > 180) return "WHITE OBJECT"; Serial.printf("R=%d G=%d B=%d\n", r, g, b); return "UNKNOWN"; } void setup() { Serial.begin(115200); k10.begin(); k10.initScreen(screen_dir); tft.init(); tft.setRotation(2); tft.fillScreen(TFT_BLACK); // Ако боите се чудни, смени true во false tft.setSwapBytes(false); setupCamera(); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.setTextSize(2); tft.drawString("Camera preview", 25, 10); delay(1000); Serial.println("SETUP DONE - STARTING LOOP"); } void loop() { camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("Camera capture failed"); return; } tft.pushImage(0, 0, 240, 280, (uint16_t *)fb->buf); String result = detectColorFromCenter(fb); esp_camera_fb_return(fb); // Center analysis rectangle tft.drawRect(80, 90, 80, 100, TFT_GREEN); tft.drawRect(81, 91, 78, 98, TFT_GREEN); // Bottom result area tft.fillRect(0, 280, 240, 40, TFT_BLACK); tft.drawRect(0, 280, 240, 40, TFT_YELLOW); tft.setTextColor(TFT_YELLOW, TFT_BLACK); tft.setTextSize(1); tft.drawString("CENTER DETECTION", 10, 284); tft.setTextColor(TFT_GREEN, TFT_BLACK); tft.setTextSize(2); tft.drawString(result, 10, 300); delay(300); }